package chebu.GPS;

import java.text.DateFormat;
import java.util.Date;
import java.util.List;

import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;


import chebu.dao.DatabaseHelper;
import chebu.dao.Localizaciones;
import android.R.string;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.provider.Settings.Secure;

import android.util.Log;

public class UpdateService extends Service implements LocationListener {
private DatabaseHelper dbHelper;
private static final int TWO_MINUTES = 1000 * 60 * 2;
private static final String TAG = UpdateService.class.getSimpleName();
private static double lat;
private static double lng;
private static Location location;
private static final int DELAY = 10000; 
LocationManager locationManager; 
Updater updater; 
public boolean isRunning = false;
public boolean saveLocation = false;
//private String android_id = Secure.getString(this.getContentResolver(),Secure.ANDROID_ID);
@Override
public IBinder onBind(Intent intent) {
	// TODO Auto-generated method stub
	return null;
}

@Override
public void onCreate() {
	super.onCreate();
	Log.d( TAG, "onCreate");
	dbHelper = new DatabaseHelper(this);
	updater = new Updater();
	locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
	
	Criteria req = new Criteria();
	req.setAccuracy(Criteria.ACCURACY_FINE);
	req.setAltitudeRequired(false);
	String bestProvider = locationManager.getBestProvider(req, true);
	Log.d(TAG,"El mejor provider es "+bestProvider);    
	
    if (locationManager.isProviderEnabled(bestProvider))
    {         
        // Update after minimum 5 minutes and if user has moved at least 100 meters.
    	Log.d(TAG,"Conectado a "+bestProvider);  
    	locationManager.requestLocationUpdates(bestProvider,DELAY, 0, this);        
        location = null;
        Location loc = getBestLocation(locationManager);       
        if(loc!=null)
        {
            lat = (Double) (loc.getLatitude());
            lng = (Double) (loc.getLongitude());
            Log.d(TAG, "La mejor posicion es lat="+lat+"+lng="+lng);
            location = loc;
            saveLocation = true;
        } 
        else
        {
        	Log.d(TAG, "La localizacion getBestLocation() es nula no salvo nada.");
        }
    }
    else
    {
    	Log.d(TAG,""+bestProvider+" Provider no habilitado");
    }
}

@Override
public synchronized void onStart(Intent intent, int startId) {
	super.onStart(intent, startId);
	Log.d( TAG, "onStart");	
	
	Log.d(TAG,"Thread isRunning = "+this.isRunning);
	
	if(!this.isRunning)
	{
		Log.d(TAG,"arranco el thread");
		updater.start();
		this.isRunning = true;
		Log.d(TAG," thread");
	}
}

@Override
public synchronized void onDestroy() {
	super.onDestroy();
	Log.d( TAG, "onDestroy");
	locationManager.removeUpdates(this);
	
	if(this.isRunning){
		try 
		{
			this.isRunning = false;
			updater.interrupt();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	Log.d( TAG, "Servicio Parado con exito");
	
}
	
public void MostrarNofiticacionGPSDesactivado()
	{
	
		final int NOTIF_ID = 1234;  
		 //string gpsDesactivadoTitulo = R.string.gpsDesactivadoTitulo;
		 //string gpsDesactivadoMensaje = R.string.gpsDesactivadoMensaje;
		 NotificationManager notifManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  
		 Notification note = new Notification(R.drawable.icon, "Gps Desactivado", System.currentTimeMillis());  
		  
		 PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(this, UpdateService.class), 0);  
		  
		 note.setLatestEventInfo(this, "Gps Desactivado", "El Gps se encuentra desactivado", intent);  
		  
		 notifManager.notify(NOTIF_ID, note); 
	}

	public static Location getBestLocation(LocationManager locationManager) {
	    Location location_gps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
	    Location location_network = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
	    // If both are available, get the most recent
	    if(location_gps!=null && location_network !=null) {
	        return (location_gps.getTime() > location_network.getTime())?location_gps:location_network;
	    }
	    else if(location_gps==null && location_network ==null){
	        return null;
	    }
	    else
	        return (location_gps==null)?location_network:location_gps;
	}

	public void onLocationChanged(Location loc) {
		lat = (Double) (loc.getLatitude());
        lng = (Double) (loc.getLongitude());
        Log.d(TAG, "Location changed lat="+lat+"+lng="+lng);
        /*Verifico que la posicion que obtuve es mejor a la anterorio gracias android*/
        if(isBetterLocation(loc,location))
        {
            location = loc;
            saveLocation = true;
        }	
	}
	
	public void onProviderDisabled(String provider) {
		locationManager.removeUpdates(this);
        lat = 0;
        lng = 0; 		
	}
	
	public void onProviderEnabled(String provider) {
		Log.d(TAG,"Provider Enabled");
		//locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, DELAY, 0, this); 	
	}
	
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
		
	}
	
	/** Determines whether one Location reading is better than the current Location fix
	  * @param location  The new Location that you want to evaluate
	  * @param currentBestLocation  The current Location fix, to which you want to compare the new one
	  */
	protected boolean isBetterLocation(Location location, Location currentBestLocation) {
	    if (currentBestLocation == null) {
	        // A new location is always better than no location
	        return true;
	    }

	    // Check whether the new location fix is newer or older
	    long timeDelta = location.getTime() - currentBestLocation.getTime();
	    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
	    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
	    boolean isNewer = timeDelta > 0;

	    // If it's been more than two minutes since the current location, use the new location
	    // because the user has likely moved
	    if (isSignificantlyNewer) {
	        return true;
	    // If the new location is more than two minutes older, it must be worse
	    } else if (isSignificantlyOlder) {
	        return false;
	    }

	    // Check whether the new location fix is more or less accurate
	    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
	    boolean isLessAccurate = accuracyDelta > 0;
	    boolean isMoreAccurate = accuracyDelta < 0;
	    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

	    // Check if the old and new location are from the same provider
	    boolean isFromSameProvider = isSameProvider(location.getProvider(),
	            currentBestLocation.getProvider());

	    // Determine location quality using a combination of timeliness and accuracy
	    if (isMoreAccurate) {
	        return true;
	    } else if (isNewer && !isLessAccurate) {
	        return true;
	    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
	        return true;
	    }
	    return false;
	}

	/** Checks whether two providers are the same */
	private boolean isSameProvider(String provider1, String provider2) {
	    if (provider1 == null) {
	      return provider2 == null;
	    }
	    return provider1.equals(provider2);
	}
	
	class Updater extends Thread
	{
		Localizaciones localizacion;
		final String TAG = Updater.class.getSimpleName();

		@Override
		public synchronized void interrupt() {
			// TODO Auto-generated method stub
			super.interrupt();
		}


		@Override
		public synchronized void run() {
			Log.d(TAG,"Thread run()");
			while (isRunning) {
				Log.d(TAG,"Thread is running");
				localizacion = new Localizaciones();
				if(saveLocation)
				{
				  try {
						Log.d(TAG, "Aca salvo la localizacion");
						lat = (Double) (location.getLatitude());
						lng = (Double) (location.getLongitude());
						Log.d(TAG, "Localizacion a guardar lat=" + lat + "+lng="+ lng);
					    OrmLiteSqliteOpenHelper helper = null;
						
						localizacion.setLatitud(lat);
						localizacion.setLongitud(lng);
						localizacion.setPasado(0);
						
						localizacion.setFecha(DateFormat.getDateInstance().format(new Date()));
						
						helper = OpenHelperManager.getHelper(getApplicationContext(), DatabaseHelper.class);
						Dao<Localizaciones, Integer> localizacionesDao = helper.getDao(Localizaciones.class);
						Log.d(TAG,"Voy a insertar localizacion = "+localizacion);
						localizacionesDao.create(localizacion);
						saveLocation = false;
					} catch (Exception e) {
						Log.e(TAG, "Error", e);
					} finally {
							OpenHelperManager.releaseHelper();
					}	  
				}
				else
				{
					Log.d(TAG, "La localizacion no cambio :D");
				}
				try 
				{
					Log.d(TAG, "Me dormi por="+DELAY);
					this.sleep(DELAY);
				} catch (InterruptedException e) 
				{
					e.printStackTrace();
				}
			}
		}
		
	}


}





